import matplotlib.pyplot as plt
import numpy as np

# 设置随机数种子
np.random.seed(5)

# ========= 准备数据 ============
# 直接采用np生成等差数列的方法，生成100个点，每个点的取值在-1~1之间
x_data = np.linspace(-1, 1, 100)
# y = 2x +1 + 噪声， 其中，噪声的维度与x_data一致
y_data = 2 * x_data + 1.0 + np.random.randn(*x_data.shape) * 0.4
# 画出随机生成数据的散点图
plt.scatter(x_data, y_data)
# 画出我们想要学习到的线性函数 y = 2x +1
plt.plot(x_data, 2 * x_data + 1.0, color='red', linewidth=3)
plt.show()

# ========= 构建模型 ============
import tensorflow as tf2
tf = tf2.compat.v1
tf.disable_eager_execution()

# 定义训练数据的占位符，x是特征值，y是标签值
x = tf.placeholder("float", name="x")
y = tf.placeholder("float", name="y")

# 定义模型函数
def model(x, w, b):
    return tf.multiply(x, w) + b


# 构建线性函数的斜率，变量w
w = tf.Variable(1.0, name="w0")
# 构建线性函数的截距，变量b
b = tf.Variable(0.0, name="b0")
# pred是预测值，前向计算
pred = model(x, w, b)

# 迭代次数（训练轮数）
train_epochs = 10
# 学习率
learning_rate = 0.05
# 采用均方差作为损失函数
loss_function = tf.reduce_mean(tf.square(y-pred))
# 梯度下降优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)

# 声明会话及变量初始化
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

# ========== 训练模型 ===========
# 开始训练，轮数为 epoch，采用SGD随机梯度下降优化方法
for epoch in range(train_epochs):
    for xs, ys in zip(x_data, y_data):
        _, loss = sess.run([optimizer, loss_function], feed_dict={x: xs, y: ys})

    b0temp = sess.run(b) #b.eval(session=sess)
    w0temp = sess.run(w) #w.eval(session=sess)
    plt.plot(x_data, w0temp * x_data + b0temp)  # 画图
plt.show()
# 打印结果
w_result = sess.run(w)
b_result = sess.run(b)
print("w: ", w_result)
print("b: ", b_result)

# 结果可视化
plt.scatter(x_data, y_data, label='Original Data')
plt.plot(x_data, x_data * w_result + b_result, label='Fitted Line')
plt.show()

# ======= 进行预测 ========
x_test = 3.21

predict = sess.run(pred, feed_dict={x: x_test})
print("预测值：%f" % predict)
